<template>
    <div class="ap_manage_container flex gap-10px">
        <el-card class="flex-1">
            <template #header>
                <span>{{ t('deviceManage.device_firmware_label') }}</span>
            </template>
            <div>
                <el-form>
                    <el-form-item :label="t('deviceManage.current_device_version_label')" label-suffix=":">
                        <span class="m-r-10px">{{ deviceCurrentFirmware.version }} </span>
                        <span>index: {{ deviceCurrentFirmware.index }}</span>
                    </el-form-item>
                </el-form>
                <div class="m-b-10px flex gap-10px">
                    <div v-globalLoading="switchApVersion" class="global_btn">
                        <svg-icon icon-class="switch" class="table_icon"></svg-icon>
                        <span class="m-l-5px">{{ t('deviceManage.switch_firmware_label') }}</span>
                    </div>
                    <div v-globalLoading="refresh" class="global_btn">
                        <div >
                            <svg-icon icon-class="refresh" class="table_icon"
                                :class="{ 'rotate-animation': isRotating }"></svg-icon>
                        </div>
                        <span class="m-l-5px">{{ t('deviceManage.refresh_firmware_label') }}</span>
                    </div>
                    <div v-globalLoading="deleteApVersion" class="global_btn">
                        <svg-icon icon-class="delete" class="table_icon"></svg-icon>
                        <span class="m-l-5px">{{ t('deviceManage.delete_firmware_label') }}</span>
                    </div>
                </div>
                <el-table :data="apVersionList">
                    <el-table-column :label="t('deviceManage.choose_label')">
                        <template v-slot="{ row }">
                            <el-radio @change="getCurrentRow(row)" v-model="radio" :value="row.index"></el-radio>
                        </template>
                    </el-table-column>
                    <el-table-column label="index">
                        <template v-slot="{ row }">
                            <span>{{ row.index }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column :label="t('deviceManage.current_device_version_label')">
                        <template v-slot="{ row }">
                            <span>{{ row.version }}</span>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </el-card>
        <el-card class="flex-1">
            <template #header>
                <span>{{ t('deviceManage.local_firmware_upgrade_label') }}</span>
            </template>
            <el-form>
                <el-form-item :label="t('deviceManage.image_path_label')" label-suffix=":">
                    <div class="flex import_firmware_container w-100% gap-10px">
                        <el-input v-model="upgradeFirmwareConfig.fileName" class="m-r-10px"></el-input>
                        <div class="global_btn" @click="importFirmware" style="min-width: 100px;">{{ t('deviceManage.import_firmware_label')
                            }}</div>
                         <div class="global_btn" style="min-width: 100px;" v-if="upgradeFirmwareConfig.file" v-globalLoading="uploadFirmware" :loading="upgradeFirmwareConfig.upLoadBtnLoading" >{{ t('deviceManage.upload_firmware_label') }}</div>
                        <input type="file" style="display: none;" ref="fileInputRef" @change="handleFileChange">
                    </div>
                </el-form-item>
                <el-form-item :label="t('deviceManage.upload_progress_label')" v-if="upgradeFirmwareConfig.showUploadProgress">
                    <div class="flex w-100%">
                    <el-progress 
                     class="w-80% m-r-10px"
                    :percentage="upgradeFirmwareConfig.uploadProgress"  
                    :text-inside="true" 
                    />
                    <div class="global_btn" v-show="upgradeFirmwareConfig.uploadProgress > 0&&upgradeFirmwareConfig.uploadProgress!==100"  @click="cancelUpload" >{{ t('deviceManage.cancel_upload_label') }}</div>
                    </div>
                </el-form-item>
                 <el-form-item :label="t('deviceManage.upgrade_progress_label')" v-if="firmwareUpgradeConfig.showUpgradeProgress">
                    <div class="flex w-100%">
                    <el-progress 
                     
                     class="w-80% m-r-10px"
                    :percentage="firmwareUpgradeConfig.progress"  
                    :text-inside="true" 
                    />
                    <div class="global_btn" v-globalLoading="handleUpgradeFirmware"  >{{ t('deviceManage.upgrade_firmware_label') }}</div>
                    </div>          
                 </el-form-item>
            </el-form>
        </el-card>
    </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
    name: 'ApManage',
})
</script>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { FirmwareManagementApi } from '@/api/firmwareManagement'
import { ElNotificationFn } from '@/utils/computedUtils'
import {OtaApi} from '@/api/ota'
import axios, { CancelTokenSource } from 'axios'
const props = defineProps<{
    upgradeType:string
}>()
const { t } = useI18n()
const isRotating = ref(false)
const refresh = async () => {
    isRotating.value = true
    await getApVersionList()
    ElNotificationFn('success', t('deviceManage.refresh_firmware_success_label'))
    setTimeout(() => {
        isRotating.value = false
    }, 1000)
}
const deviceCurrentFirmware = ref<any>({
    version:'',
    index:''
})
const apVersionList = ref([])
const currentRow = ref('')
const radio = ref('')
async function getApVersionList() {
    const { data } = await FirmwareManagementApi.reqGetApVersionList()
    apVersionList.value = data.list
}
async function getCurrentApVersion() {
    const { data } = await FirmwareManagementApi.reqGetCurrentApVersion()
    deviceCurrentFirmware.value.version = data.version
    deviceCurrentFirmware.value.index = data.index
    radio.value = data.index
    currentRow.value = data
}
async function switchApVersion() {
    if (!currentRow.value) {
        ElNotificationFn('warning', t('deviceManage.not_choose_label'))
    }
    await FirmwareManagementApi.reqSwitchApVersion(currentRow.value)
    await new Promise(resolve => setTimeout(resolve, 2000))
    await getCurrentApVersion()
    ElNotificationFn('success', t('deviceManage.switch_ap_version_success_label'))
}
async function deleteApVersion() {
    await FirmwareManagementApi.reqDeleteApVersion(currentRow.value)
    await getApVersionList()
    await getCurrentApVersion()
    ElNotificationFn('success', t('deviceManage.delete_ap_version_success_label'))
}
function getCurrentRow(row: any) {
    currentRow.value = row
}
const upgradeFirmwareConfig = ref<any>({
    file:null,
    fileName:'',
    upLoadBtnLoading:false,
    uploadProgress:0,
    showUploadProgress:false
})
let cancelToken:CancelTokenSource | null = null
interface ProgressEvent{
    loaded:number,
    total:number
}
function uploadProgressFn(progress:ProgressEvent){
    upgradeFirmwareConfig.value.uploadProgress = Math.round((progress.loaded / progress.total) * 100)
}
function cancelUpload(){
    if (cancelToken) {
        cancelToken.cancel()
    }
    upgradeFirmwareConfig.value.uploadProgress = 0
    upgradeFirmwareConfig.value.upLoadBtnLoading = false
    upgradeFirmwareConfig.value.showUploadProgress = false
    cancelToken = null  
}
const fileInputRef = ref()
function importFirmware(){
    fileInputRef.value.click()
}
const handleFileChange = (event: any) => {
    const file = event.target.files[0];
    upgradeFirmwareConfig.value.file = file;
    upgradeFirmwareConfig.value.fileName = file.name
    upgradeFirmwareConfig.value.showUploadProgress = false
    upgradeFirmwareConfig.value.progress = 0
    firmwareUpgradeConfig.value.progress = 0
    firmwareUpgradeConfig.value.showUpgradeProgress = false
};
async function uploadFirmware(){
    upgradeFirmwareConfig.value.upLoadBtnLoading = true
    upgradeFirmwareConfig.value.showUploadProgress = true
    try {
        const formData = new FormData()
        formData.append('filedata',upgradeFirmwareConfig.value.file)
        formData.append('filename',upgradeFirmwareConfig.value.fileName)
        cancelToken = axios.CancelToken.source()
        await OtaApi.uploadFile(formData,uploadProgressFn,cancelToken.token)
        ElNotificationFn('success',t('deviceManage.upload_firmware_success_label'))
        firmwareUpgradeConfig.value.showUpgradeProgress = true
    } catch (error) {
        if (axios.isCancel(error)) {
            ElNotificationFn('info',t('deviceManage.cancel_upload_label'))
        } else {
            ElNotificationFn('error',t('deviceManage.upload_firmware_failure_label'))
        }
    }finally{
        upgradeFirmwareConfig.value.upLoadBtnLoading = false
    } 
}
const firmwareUpgradeConfig = ref<any>({
    progress:0,
    upgradeBtnLoading:false,
    showUpgradeProgress:false
})
async function handleUpgradeFirmware(){
    if(!upgradeFirmwareConfig.value.fileName){
        ElNotificationFn('warning',t('deviceManage.not_choose_firmware_label'))
        return
    }
    firmwareUpgradeConfig.value.upgradeBtnLoading = true
    try {
        await OtaApi.reqUpgradeFirmware({
            filename:upgradeFirmwareConfig.value.fileName,
            type:props.upgradeType
        })
        await new Promise(resolve => setTimeout(resolve, 5000))
        getUpgradeStatus()
    } catch (error) {
        ElNotificationFn('error',t('deviceManage.upgrade_firmware_failure_label'))
    }finally{
        firmwareUpgradeConfig.value.upgradeBtnLoading = false
    }
}
let  upgradeTimer:any = null
const getUpgradeStatus = async () => {
  if (upgradeTimer) {
    clearTimeout(upgradeTimer)
  }
  try {
    const { data } = await OtaApi.reqGetUpgradeStatus({
    filename: upgradeFirmwareConfig.value.fileName,
    type: props.upgradeType
  })
  firmwareUpgradeConfig.value.progress = data.progress
  switch (data.status) {
    case 'success':
      ElNotificationFn('success',t('deviceManage.upgrade_firmware_success_label'))
      await nextTick()
      firmwareUpgradeConfig.value.upgradeBtnLoading = false
      break
    case 'failed':
      ElNotificationFn('error',t('deviceManage.upgrade_firmware_failure_label'))
      await nextTick()
      firmwareUpgradeConfig.value.upgradeBtnLoading = false
      break
    default:
      upgradeTimer = setTimeout(() => {
        getUpgradeStatus()
      }, 2000)
  }
  } catch (error) {
    ElNotificationFn('error',t('deviceManage.upgrade_firmware_failure_label'))
  }finally{
    firmwareUpgradeConfig.value.upgradeBtnLoading = false
  }
}
onMounted(() => {
    getApVersionList()
    getCurrentApVersion()
})
onUnmounted(() => {
  if (upgradeTimer) {
    clearTimeout(upgradeTimer)
    upgradeTimer = null
  }
})
</script>

<style lang="scss" scoped>
@import '@/styles/input.scss';
@import '@/styles/form.scss';
@import '@/styles/table.scss';
@import '@/styles/progress.scss';
.ap_manage_container {
    .table_icon {
        width: 18px;
        height: 18px;
    }

    :deep(.el-radio__label) {
        display: none;
    }

    @keyframes rotate {
        from {
            transform: rotate(0deg);
        }

        to {
            transform: rotate(360deg);
        }
    }

    .el-card {
        background: transparent;
        color: #fff;
        border: none;
    }

    .import_firmware_container {
        .el-input {
            width: 80%;
        }
    }

    .rotate-animation {
        animation: rotate 1s linear;
    }

    :deep(.el-progress-bar__outer){
        height: 26px !important;
    }

}
</style>
